#ifndef _MY_COMMON_H_
#define _MY_COMMON_H_

#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/in.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/namei.h>
#include <linux/dirent.h>
#include <linux/kobject.h>
#include <linux/ip.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/list.h>
#include <linux/ptrace.h>
#include <linux/spinlock.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <net/tcp.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>

/* todo
 * use down or down_read, down_write to use sem to protect
 */ 


#define NUM_NEED 4
#define FUNC_OFFSET (3 * sizeof(int))

static unsigned int saved_st[NUM_NEED];
/* target_func  must be init before hijack */
static void *target_func = NULL;

static void clean_cache(void *p1, void *p2)
{
    __asm__ __volatile__ (
        "mcr p15, 0, %0, c7, c14, 1\n"        
        ::"r"(p1));
    __asm__ __volatile__ (
        "mcr p15, 0, %0, c7, c14, 1\n"        
        ::"r"(p2));    

    __asm__ __volatile__ (
        "mcr p15, 0, %0, c7, c5, 0\n"
        ::"r"(0));
}

extern void jmpfunc(void);

static int hijack_func(void)
{
    void *pjmpfunc;

    pjmpfunc = (void *)jmpfunc;

    memcpy(target_func, pjmpfunc + FUNC_OFFSET, sizeof(int) * NUM_NEED);

    clean_cache(target_func, target_func + NUM_NEED);
    return (0);
}



static int save_old(void *func)
{
    memcpy(saved_st, func, sizeof(int) * NUM_NEED);
    return (0);
}


#endif /* _VLOG_COMMON_H_ */

